package helper

import (
	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"

	"fiber/global"
	// "fmt"
)

type Response struct {
	Code int         `json:"code"`
	Data interface{} `json:"data"`
	Msg  string      `json:"msg"`
}

var (
	response = new(Response)
	// code int
	// msg string
)

// 成功返回
func Success(c *fiber.Ctx, data interface{}, args ...interface{}) error {
	// 语法糖处理
	argsHandler(true, args)
	response.Data = data

	// 将返回记录进日志
	ResponseLog(c)

	return c.Status(fiber.StatusOK).JSON(response)
}

/*
*
错误返回
错都错了，要什么data
*/
func Fail(c *fiber.Ctx, args ...interface{}) error {

	// 语法糖处理
	argsHandler(false, args)
	// response.Data = data

	// 将返回记录进日志
	ResponseLog(c)

	return c.Status(fiber.StatusOK).JSON(response)
}

/*
*
返回数据写入日志
*/
func ResponseLog(c *fiber.Ctx) {

	global.Log.Info(
		"返回数据：\n",
		// zap.Stack("test"),
		zap.String("request_id", c.GetRespHeader("X-Request-Id")), // 使用requestId绑定记录
		zap.Int("code", response.Code),
		zap.String("msg", response.Msg),
		zap.Reflect("data", response.Data),
	)

}

/*
*
处理语法糖  这里有个二次传递参数值改变的问题...
针对Response
response_type 返回类型 true:成功 false:失败
*/
func argsHandler(response_type bool, args []interface{}) {

	// 重新初始化一次response，否则他会记录到上次返回的response
	response = new(Response)
	// response.Data = nil

	var (
		msg  string
		code int
	)

	if response_type {
		msg = global.SuccessMsg
		code = global.SuccessStatus
	} else {
		msg = global.FailMsg
		code = global.FailStatus
	}

	// 根据语法糖得到code，msg的值
	for _, arg := range args {
		switch t := arg.(type) {
		case string:
			msg = t
		case int:
			code = t
		}
	}

	// 直接绑定结构体
	// response.(Response)	// 失败，后期再看看

	response.Msg = msg
	response.Code = code
}
